#include <Arduino.h>
#include <U8g2lib.h>

#include <WiFi.h>

#include <RDA5807.h>
#include <SPI.h>
#include <Wire.h>



//wifi info
char* ssid     = "iron2222";
char* password = "18436099009"; 

//time
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;

//OLED引脚设置
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ 37, /* dc=*/ 33, /* reset=*/ 34);

// I2C bus pin on ESP32
#define ESP32_I2C_SDA 5
#define ESP32_I2C_SCL 4

#define MAX_DELAY_RDS 40   // 40ms - polling method

long rds_elapsed = millis();

RDA5807 rx;

//按键
int button1Pin = 1;    
int button2Pin = 2;    
int button3Pin = 3;     
int button4Pin = 6;  

String ipaddress;

void setup() {
  Serial.begin(115200);
  u8g2.begin(); 
  dispwelcome();    //显示欢迎画面
  
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户正在尝试WiFi连接
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
    Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。                                           
  Serial.println("");                          // WiFi连接成功后
  Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
  ipaddress = WiFi.localIP().toString();

  // The line below may be necessary to setup I2C pins on ESP32
  Wire.begin(ESP32_I2C_SDA, ESP32_I2C_SCL);
  rx.setup();
  rx.setVolume(2);
  delay(500);
  // Select a station with RDS service in your place
  rx.setFrequency(10650); // It is the frequency you want to select in MHz multiplied by 100.
  // Enables SDR
  rx.setRDS(true);
  
  pinMode(button1Pin, INPUT_PULLUP); //输入模式
  pinMode(button2Pin, INPUT_PULLUP);
  pinMode(button3Pin, INPUT_PULLUP);
  pinMode(button4Pin, INPUT_PULLUP);
  pinMode(41, OUTPUT);
  pinMode(42, OUTPUT);

  // 从网络时间服务器上获取并设置时间
  // 获取成功后芯片会使用RTC时钟保持时间的更新
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();
}

uint8_t modelsign = 0; //默认为无输出
void loop() {

  if (modelsign == 0)
  {
    delay(1000);
    timer_show();
    printLocalTime();
  }
  
   
   if (digitalRead(button1Pin) == LOW)
   {
       modelsign++;
   }

   if (modelsign == 1)
   {
    selectDevice(1);
    FM_show();
    if (digitalRead(button2Pin) == LOW)
    {
      rx.setFrequencyUp();
    }
    if (digitalRead(button3Pin) == LOW)
    {
      rx.setVolumeUp();
    }
    if (digitalRead(button4Pin) == LOW)
    {
      rx.setVolumeDown();
    }      
   } 
   if (modelsign == 2)
   {
    selectDevice(2);
    dispwelcome();
    }
}

void dispwelcome() {
  u8g2.firstPage();
  u8g2.clearBuffer();         //清除内部缓冲区
  u8g2.setFontDirection(0);   //设置字体方向
  u8g2.setFont(u8g2_font_ncenB14_tr);     //设置字体
  u8g2.setCursor(0, 40);
  u8g2.print("Hello Jarvis!");
  u8g2.sendBuffer();
  delay(1000);
}

void timer_show() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
    {
        u8g2.clearBuffer();
        u8g2.setFontDirection(0);
        u8g2.setFont(u8g2_font_ncenB08_tr);
        u8g2.setCursor(0, 40);
        u8g2.print("Failed to obtain time");
        u8g2.setCursor(2,55);
        u8g2.print(ipaddress);
        u8g2.sendBuffer();
        return;
    }
  u8g2.clearBuffer();
  u8g2.setFontDirection(0);
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.setCursor(20, 15);
  u8g2.print(&timeinfo, "%H:%M:%S");
  u8g2.setCursor(15, 35);
  u8g2.print(&timeinfo, "%Y/%m/%d");
  u8g2.setCursor(2,55);
  u8g2.print(ipaddress);
  u8g2.sendBuffer();
}

void printLocalTime()
{
    struct tm timeinfo;
    if (!getLocalTime(&timeinfo))
    {
        Serial.println("Failed to obtain time");
        return;
    }
    Serial.println(&timeinfo, "%F %T %A"); // 格式化输出
}


//0：时间显示 1:FM收音机 2:网络电台
void selectDevice(uint8_t dev) {
  if(dev == 0) {
    digitalWrite(41, LOW);
    digitalWrite(42, LOW);
  }
  if(dev == 1) {
    digitalWrite(41, HIGH);
    digitalWrite(42, LOW);
  }
  if(dev == 2) {
    digitalWrite(41, HIGH);
    digitalWrite(42, HIGH);
  }
}

void FM_show() {
  char str[64] = {0};
  u8g2.firstPage();
  u8g2.clearBuffer();         //清除内部缓冲区
  u8g2.setFontDirection(0);   //设置字体方向
  
  u8g2.setFont(u8g2_font_ncenB14_tr);     //设置字体
  u8g2.setCursor(15, 20);
  u8g2.print("FM Radio");

  u8g2.setFont(u8g2_font_ncenB10_tf);  
  u8g2.setCursor(15, 40);
  sprintf(str, "%u MHz",rx.getFrequency() );
  u8g2.print(str);
  u8g2.setCursor(15, 55);
  sprintf(str, "Vol: %2.2u",rx.getVolume());
  u8g2.print(str);
  
  
  u8g2.sendBuffer();
  delay(1000);
}
